package com.tsq.weixin.provider.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tsq.web.base.service.impl.BaseServiceImpl;
import com.tsq.weixin.api.enums.ArticleTypeEnum;
import com.tsq.weixin.api.exception.RRException;
import com.tsq.weixin.api.model.Article;
import com.tsq.weixin.provider.mapper.ArticleMapper;
import com.tsq.weixin.provider.service.ArticleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.Date;
import java.util.List;

@Service
@Transactional(rollbackFor = Exception.class)
public class ArticleServiceImpl extends BaseServiceImpl<ArticleMapper, Article> implements ArticleService {

    private static final String ID_PLACEHOLDER = "${articleId}";
    /**
     * 查询文章列表时返回的字段（过滤掉详情字段以加快速度）
     */
    private static final String LIST_FILEDS = "id,summary,image,sub_category,update_time,title,type,tags,create_time,target_link,open_count,category";

    @Autowired
    ArticleMapper articleMapper;

    @Override
    public Article findById(int articleId) {

        if (articleId <= 0) {
            return null;
        }
        Article article = this.baseMapper.selectById(articleId);
        if (article != null) {
            this.baseMapper.addOpenCount(articleId);
        }
        return article;
    }

    @Override
    public List<Article> selectCategory(ArticleTypeEnum articleType, String category) {

        return this.list(new QueryWrapper<Article>()
                .select(LIST_FILEDS)
                .eq("type", articleType.getValue())
                .eq("category", category));
    }

    @Override
    public List<Article> search(ArticleTypeEnum articleType, String category, String keywords) {

        return this.list(new QueryWrapper<Article>()
                .select(LIST_FILEDS)
                .eq("type", articleType.getValue())
                .eq(!StringUtils.isEmpty(category), "category", category)
                .and(i -> i.like("summary", keywords).or().like("title", keywords)));
    }

    @Override
    public IPage<Article> queryPage(Article article) {

        String title = article.getTitle();
        String type = String.valueOf(article.getType());
        String category = article.getCategory();
        String subCategory = article.getSubCategory();
        long currentPage = article.getCurrent();
        long pageSize = article.getSize();

        return this.baseMapper.selectPage(new Page<>(currentPage,pageSize),new QueryWrapper<Article>().select(LIST_FILEDS)
                .eq(!StringUtils.isEmpty(type), "type", type)
                .like(!StringUtils.isEmpty(category), "category", category)
                .like(!StringUtils.isEmpty(subCategory), "sub_category", subCategory)
                .like(!StringUtils.isEmpty(title), "title", title));
    }

    @Override
    public boolean save(Article article){

        article.setUpdateTime(new Date());
        if (article.getId() > 0) {
            articleMapper.updateById(article);
        } else {
            String title = article.getTitle();
            int count = articleMapper.selectCount(new QueryWrapper<Article>()
                            .eq("title", title)
                            .eq("category", article.getCategory())
                            .eq("sub_category", article.getSubCategory())
            );
            if (count > 0){
                throw new RRException("同目录下文章[" + title + "]已存在，不可重复添加");
            }
            article.setCreateTime(new Date());
            articleMapper.insert(article);
        }
        String targetLink = article.getTargetLink();
        if (targetLink.contains(ID_PLACEHOLDER)) {
            article.setTargetLink(targetLink.replace(ID_PLACEHOLDER, article.getId() + ""));
            articleMapper.updateById(article);
        }
        return true;
    }

}
